#include "AppImpGL.h"
#include "obj_impgl/ObjLineImpGL.h"
#include "obj_impgl/ObjFactoryImpGL.h"
#include "obj_impgl/ObjAxis3ImpGL.h"

AppImpGL* AppImpGL::GetInstance()
{
	static AppImpGL* s_instance = NULL;
	if(NULL == s_instance)
		s_instance = new AppImpGL();
	return s_instance;
}


AppImpGL::~AppImpGL(void)
{
}

void OnDisplay()
{
	AppImpGL::GetInstance()->Update();
	AppImpGL::GetInstance()->Paint();
}
void OnReshape(int w, int h)
{
	AppImpGL::GetInstance()->EventReshape(w, h);
}
void OnTimer(int value)
{
	AppImpGL::GetInstance()->EventTimer(value);
}
void OnKeyboard(unsigned char key, int x, int y)
{
	AppImpGL::GetInstance()->EventKeyboard(key, x, y);
}
void OnMouse(int button, int state, int x, int y)
{
	AppImpGL::GetInstance()->EventMouse(button, state, x, y);
}
void OnMotion(int x, int y)
{
	AppImpGL::GetInstance()->EventMotion(x, y);
}

bool AppImpGL::InitApp(const char* title, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
	m_title = title;
	glutInit((int*)arg1, (char**)arg2);
	m_displayMode = GLUT_DOUBLE | GLUT_RGB;
	glutInitDisplayMode(m_displayMode);
	m_shadeModel = GL_FLAT;
	glShadeModel(m_shadeModel);

	return true;
}


bool AppImpGL::Create(int w, int h)
{
	m_windowWidth = w;
	m_windowHeight = h;
	glutInitWindowSize(m_windowWidth, m_windowHeight);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(m_title.c_str());
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(m_shadeModel);

	glutDisplayFunc(OnDisplay);
	glutReshapeFunc(OnReshape);
	glutKeyboardFunc(OnKeyboard);
	glutMouseFunc(OnMouse);
	glutMotionFunc(OnMotion);
	glutTimerFunc(20, OnTimer, 0);

	return true;
}


void AppImpGL::MainLoop()
{
	m_scene.reset(new Scene());
	m_scene->Init();
	glutMainLoop();
}

void AppImpGL::Update()
{
	glViewport(0, 0, m_windowWidth, m_windowHeight);
	glLoadIdentity();
	gluLookAt(3.0, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	m_scene->Update();
}

void AppImpGL::Paint()
{
	m_scene->Paint();

	glutSwapBuffers();
}

void AppImpGL::EventReshape(int w, int h)
{
	m_windowWidth = w; 
	m_windowHeight = h;
	glClear(GL_COLOR_BUFFER_BIT);
	glViewport(0, 0, m_windowWidth, m_windowHeight);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, m_windowWidth/(double)m_windowHeight, 1.5, 200);
	glMatrixMode(GL_MODELVIEW);
}

void AppImpGL::EventTimer(int value)
{
	if(value == 0)
	{
		glutPostRedisplay();
		glutTimerFunc(20, OnTimer, 0);
	}
}

void AppImpGL::EventKeyboard(unsigned char key, int x, int y)
{
}

void AppImpGL::EventMouse(int button, int state, int x, int y)
{
}

void AppImpGL::EventMotion(int x, int y)
{
}